import path from 'path';
import fs from 'fs';
import {PagesOptions} from '../types';
import {Logger} from 'vite';

/**
 * 类型生成器，用于生成页面路径的TypeScript类型定义
 */
export class TypesGenerator {

  /**
   * 根据pages.json生成TypeScript类型定义
   * @param pagesJson pages.json内容
   * @param outputPath 输出路径
   * @param logger 日志记录器
   */
  public static generateTypes(pagesJson: PagesOptions, outputPath: string, logger: Logger): void {
    try {
      // 收集所有页面路径
      const allPaths = this.collectAllPaths(pagesJson);

      // 生成类型定义内容
      const typesContent = this.generateTypesContent(allPaths);

      // 确保输出目录存在
      const outputDir = path.dirname(outputPath);
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, {recursive: true});
      }

      // 写入类型定义文件
      fs.writeFileSync(outputPath, typesContent, 'utf-8');

      logger.info(`已生成页面路径类型定义: ${outputPath}`);
    } catch (error) {
      logger.error(`生成页面路径类型定义失败: ${error}`);
    }
  }

  /**
   * 收集所有页面路径
   * @param pagesJson pages.json内容
   * @returns 所有页面路径数组
   */
  private static collectAllPaths(pagesJson: PagesOptions): string[] {
    const paths: string[] = [];

    // 收集主包页面路径
    if (pagesJson.pages) {
      for (const page of pagesJson.pages) {
        paths.push(`/${page.path}`);
      }
    }

    // 收集分包页面路径
    if (pagesJson.subPackages) {
      for (const subPackage of pagesJson.subPackages) {
        if (subPackage.pages) {
          for (const page of subPackage.pages) {
            // 确保路径正确拼接，避免多余的斜杠
            const subPath = `/${subPackage.root}/${page.path}`.replace(/\/+/g, '/');
            paths.push(subPath);
          }
        }
      }
    }

    return paths;
  }

  /**
   * 生成类型定义内容
   * @param paths 页面路径数组
   * @returns 类型定义内容
   */
  private static generateTypesContent(paths: string[]): string {
    const pathsUnion = paths.map(path => `'${path}'`).join(' | ');

    return `// auto-pages generate

/**
 * 所有页面路径的联合类型
 */
export type UniPagesPath = ${pathsUnion || 'string'};

export type NavigateToOptions = UniNamespace.NavigateToOptions & {
  url: UniPagesPath;
}

export type RedirectToOptions = UniNamespace.RedirectToOptions & {
  url: UniPagesPath;
}

export type ReLaunchOptions = UniNamespace.ReLaunchOptions & {
  url: UniPagesPath;
}

export type SwitchTabOptions = UniNamespace.SwitchTabOptions & {
  url: UniPagesPath;
}

declare global {
  namespace uni {
    function navigateTo(options: NavigateToOptions): void;
    function redirectTo(options: RedirectToOptions): void;
    function reLaunch(options: ReLaunchOptions): void;
    function switchTab(options: SwitchTabOptions): void;
  }
}

export {};
`;
  }
}
